/*
 * Copyright 2010 (c) Dou Yongwang (douyongwang@gmail.com)
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

#include <e32cons.h>
#include <f32file.h>


_LIT(kJSONTest, "JSON-Test");
_LIT(KTxtTestSJON, "TestJSON");
_LIT(KFormatFailed,"failed: leave code=%d");
_LIT(KTxtOK,"ok");
_LIT(KTxtPressAnyKey," [press any key]");

#include <sjson.h>
#include <sjson_template.h>

using namespace sjson;
using namespace sjson_template;

// public
LOCAL_D CConsoleBase* console; // write all your messages to this

LOCAL_C void show(const TDesC8& aDesC)
	{
	HBufC* json2 = HBufC::NewLC(aDesC.Length());
	json2->Des().Copy(aDesC);
	console->Printf(*json2);
	CleanupStack::PopAndDestroy(json2); //
	}

LOCAL_C void SaveFileL(const TDesC& aFileName, const TDesC8& aData)
	{
	RFs fs;
	User::LeaveIfError(fs.Connect());
	CleanupClosePushL(fs);
	
	TFileName filePath;
	fs.PrivatePath(filePath);
//	filePath.Append(_L("output\\"));
	filePath.Append(aFileName);
	
//	User::LeaveIfError(fs.MkDirAll(filePath));

	RFile file;
	User::LeaveIfError(file.Replace(fs, filePath, EFileShareAny|EFileWrite));
	CleanupClosePushL(file);
	User::LeaveIfError(file.Write(aData));
	CleanupStack::PopAndDestroy(2, &fs); // file, fs
	}

LOCAL_C HBufC8* LoadPrivateFileL(const TDesC& aRelativePath, const TDesC& aFileName)
	{
	RFs fs;
	User::LeaveIfError(fs.Connect());
	CleanupClosePushL(fs);
	
	TFileName filePath;
	fs.PrivatePath(filePath);
	filePath.Append(aRelativePath);
	filePath.Append(aFileName);
	
	RFile file;
	User::LeaveIfError(file.Open(fs, filePath, EFileShareAny|EFileRead));
	CleanupClosePushL(file);
	TInt size;
	file.Size(size);
	HBufC8* buf = HBufC8::NewLC(size);
	TPtr8 ptr =buf->Des();
	file.Read(ptr, size);
	CleanupStack::Pop(buf);
	CleanupStack::PopAndDestroy(2, &fs); // file, fs
	return buf;
	}

LOCAL_C HBufC8* LoadTemplateFileL(const TDesC& aFileName)
	{
	return LoadPrivateFileL(_L("template\\"), aFileName);
	}

LOCAL_C HBufC8* LoadJSONFileL(const TDesC& aFileName)
	{
	return LoadPrivateFileL(_L("json\\"), aFileName);
	}

LOCAL_C void RenderL(const TDesC& aTemplateFileName, TAny* aContext)
	{
	HBufC8* templateStr = LoadTemplateFileL(aTemplateFileName);
	CleanupStack::PushL(templateStr);
	CTemplate* tpt = CTemplate::NewLC(*templateStr);
	tpt->RenderL((CContext*)aContext, NULL);

	SaveFileL(_L("render.txt"), tpt->Result());

	CleanupStack::PopAndDestroy(2, templateStr); // tpt templateStr
	}

void testTemplateRenderL()
	{
	_LIT(KJSONFile, "test.json");
	_LIT(KTemplateFile, "test.tpl");
	
	HBufC8* jsonContext = LoadJSONFileL(KJSONFile);
	
	CJSONValue* value = CJSONValue::NewL();
	value->Parse(*jsonContext);
	delete jsonContext;
	
	RenderL(KTemplateFile, value);
	delete value;
	}

LOCAL_C void doTestsL()
	{
	testTemplateRenderL();
	}

LOCAL_C void callExampleL() // initialize and call example code under cleanup stack
    {
	console=Console::NewL(KTxtTestSJON,TSize(KConsFullScreen,KConsFullScreen));
	CleanupStack::PushL(console);
	TRAPD(error,doTestsL()); // perform example function
	if (error)
		console->Printf(KFormatFailed, error);
	else
		console->Printf(KTxtOK);
	console->Printf(KTxtPressAnyKey);
	console->Getch(); // get and ignore character
	CleanupStack::PopAndDestroy(); // close console
    }

GLDEF_C TInt E32Main() // main function called by E32
    {
	__UHEAP_MARK;
	CTrapCleanup* cleanup=CTrapCleanup::New(); // get clean-up stack
	TRAPD(error,callExampleL()); // more initialization, then do example
	__ASSERT_ALWAYS(!error,User::Panic(kJSONTest, error));
	delete cleanup; // destroy clean-up stack
	__UHEAP_MARKEND;
	return 0; // and return
    }
